#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
后门检测模块
检测系统中可能存在的后门和持久化机制
"""

from __future__ import print_function

import os
import platform
from core.utils import ml, color, color_red, color_title, system_info, safe_print
from core.distro_detection import detect_linux_distro
from .ssh_checks import check_ssh_service_status

# Python 2/3 兼容性
import sys
if sys.version_info[0] == 2:
    string_types = basestring
    text_type = unicode
    def iteritems(d):
        return d.iteritems()
    def itervalues(d):
        return d.itervalues()
else:
    string_types = str
    text_type = str
    def iteritems(d):
        return d.items()
    def itervalues(d):
        return d.values()

def _get_platform_command(command_type):
    """获取平台特定的命令"""
    system = platform.system().lower()
    
    commands = {
        'whoami': {
            'windows': 'whoami',
            'linux': 'whoami',
            'darwin': 'whoami'
        },
        'ps_aux': {
            'windows': 'powershell "Get-Process | Select-Object ProcessName,Id,CPU | Format-Table -AutoSize"',
            'linux': 'ps aux',
            'darwin': 'ps aux'
        },
        'uname_r': {
            'windows': 'powershell "[System.Environment]::OSVersion.Version"',
            'linux': 'uname -r',
            'darwin': 'uname -r'
        },
        'uname_m': {
            'windows': 'powershell "[System.Environment]::Is64BitOperatingSystem"',
            'linux': 'uname -m',
            'darwin': 'uname -m'
        },
        'ps_grep_strace': {
            'windows': 'powershell "Get-Process | Where-Object {$_.ProcessName -like \'*trace*\'} | Format-Table -AutoSize"',
            'linux': 'ps aux | grep strace | grep -v grep',
            'darwin': 'ps aux | grep strace | grep -v grep'
        }
    }
    
    if command_type in commands:
        return commands[command_type].get(system, commands[command_type].get('linux', ''))
    
    return ''

def _execute_platform_command(command_type):
    """执行平台特定的命令"""
    try:
        cmd = _get_platform_command(command_type)
        if cmd:
            return ml(cmd).strip()
        return ''
    except Exception:
        return ''

def check_alerts():
    """检查别名后门条件"""
    color_title("别名后门条件检测")
    
    conditions_met = []
    
    try:
        # 条件1: 检查shell类型
        try:
            shell_env = os.environ.get('SHELL', '')
            if shell_env:
                conditions_met.append("条件满足: 检测到shell环境")
                color("✓ 检测到shell环境: {}".format(shell_env))
            else:
                # Windows环境检查
                if os.name == 'nt':
                    conditions_met.append("条件满足: Windows环境")
                    color("✓ 检测到Windows环境")
                else:
                    color("○ 未检测到shell环境")
        except Exception:
            color("○ 无法检测shell环境")
        
        # 条件2: 检查别名设置权限
        try:
            # 测试别名设置
            if os.name == 'nt':
                # Windows环境使用PowerShell别名
                test_result = ml('powershell "Set-Alias test-alias Get-Process; Get-Alias test-alias"')
                if 'test-alias' in test_result:
                    conditions_met.append("条件满足: 可设置别名")
                    color("✓ 可设置别名 (PowerShell)")
                else:
                    color("○ 无法设置别名")
            else:
                # Linux/Unix环境
                test_result = ml('alias test_alias="echo test" && alias | grep test_alias')
                if 'test_alias' in test_result:
                    conditions_met.append("条件满足: 可设置别名")
                    color("✓ 可设置别名")
                    # 清理测试别名
                    ml('unalias test_alias 2>/dev/null')
                else:
                    color("○ 无法设置别名")
        except Exception:
            color("○ 无法测试别名设置")
        
        # 条件3: 检查配置文件写入权限
        try:
            if os.name == 'nt':
                # Windows环境检查PowerShell配置文件
                profile_path = ml('powershell "$PROFILE"').strip()
                if profile_path and os.path.exists(os.path.dirname(profile_path)):
                    conditions_met.append("条件满足: 可访问PowerShell配置")
                    color("✓ 可访问PowerShell配置文件")
                else:
                    color("○ 无法访问PowerShell配置文件")
            else:
                # Linux/Unix环境检查shell配置文件
                config_files = ['~/.bashrc', '~/.zshrc', '~/.profile']
                writable_configs = []
                for config_file in config_files:
                    expanded_path = os.path.expanduser(config_file)
                    if os.path.exists(expanded_path) and os.access(expanded_path, os.W_OK):
                        writable_configs.append(config_file)
                
                if writable_configs:
                    conditions_met.append("条件满足: 可写入配置文件")
                    color("✓ 可写入配置文件: {}".format(', '.join(writable_configs)))
                else:
                    color("○ 无法写入配置文件")
        except Exception:
            color("○ 无法检测配置文件权限")
        
        # 条件4: 检查环境变量设置权限
        try:
            # 测试环境变量设置
            if os.name == 'nt':
                # Windows环境
                test_result = ml('powershell "$env:TEST_VAR=\'test\'; $env:TEST_VAR"')
                if 'test' in test_result:
                    conditions_met.append("条件满足: 可设置环境变量")
                    color("✓ 可设置环境变量 (PowerShell)")
                else:
                    color("○ 无法设置环境变量")
            else:
                # Linux/Unix环境
                test_result = ml('export TEST_ALIAS_VAR="test" && echo $TEST_ALIAS_VAR')
                if 'test' in test_result:
                    conditions_met.append("条件满足: 可设置环境变量")
                    color("✓ 可设置环境变量")
                    # 清理测试变量
                    ml('unset TEST_ALIAS_VAR 2>/dev/null')
                else:
                    color("○ 无法设置环境变量")
        except Exception:
            color("○ 无法测试环境变量设置")
        
        # 条件5: 检查命令执行权限
        try:
            whoami_result = _execute_platform_command('whoami')
            if whoami_result:
                conditions_met.append("条件满足: 具备命令执行权限")
                color("✓ 具备命令执行权限 (当前用户: {})".format(whoami_result))
            else:
                color("○ 命令执行权限受限")
        except Exception:
            color("○ 无法检测命令执行权限")
        
        # 总结条件检测结果
        color_title("别名后门条件总结")
        if conditions_met:
            color("满足 {} 个别名后门条件:".format(len(conditions_met)))
            for condition in conditions_met:
                color("  • {}".format(condition))
        else:
            color("未满足别名后门的基本条件")
            
    except Exception as e:
        color_red("别名后门条件检测失败: {}".format(e))


def check_crontab():
    """检查crontab后门条件"""
    color_title("Crontab后门条件检测")
    
    conditions_met = []
    
    try:
        # 条件1: 检查cron服务状态
        try:
            if os.name == 'nt':
                # Windows环境检查任务计划服务
                service_result = ml('powershell "Get-Service -Name Schedule | Select-Object Status"')
                if 'Running' in service_result:
                    conditions_met.append("条件满足: 任务计划服务运行中")
                    color("✓ 任务计划服务运行中")
                else:
                    color("○ 任务计划服务未运行")
            else:
                # Linux/Unix环境检查cron服务
                cron_status = check_ssh_service_status('cron')
                if cron_status == 'active':
                    conditions_met.append("条件满足: cron服务运行中")
                    color("✓ cron服务运行中")
                elif cron_status == 'inactive':
                    color("○ cron服务未运行")
                else:
                    color("○ 无法检测cron服务状态")
        except Exception:
            color("○ 无法检测定时任务服务状态")
        
        # 条件2: 检查系统cron目录权限
        try:
            if os.name == 'nt':
                # Windows环境检查任务计划目录
                task_dir = r'C:\Windows\System32\Tasks'
                if os.path.exists(task_dir) and os.access(task_dir, os.R_OK):
                    conditions_met.append("条件满足: 可访问任务计划目录")
                    color("✓ 可访问任务计划目录")
                else:
                    color("○ 无法访问任务计划目录")
            else:
                # Linux/Unix环境检查cron目录
                cron_dirs = ['/etc/cron.d', '/etc/cron.daily', '/etc/cron.hourly', '/etc/cron.monthly', '/etc/cron.weekly']
                accessible_dirs = []
                for cron_dir in cron_dirs:
                    if os.path.exists(cron_dir) and os.access(cron_dir, os.R_OK):
                        accessible_dirs.append(cron_dir)
                
                if accessible_dirs:
                    conditions_met.append("条件满足: 可访问系统cron目录")
                    color("✓ 可访问系统cron目录: {}".format(len(accessible_dirs)))
                else:
                    color("○ 无法访问系统cron目录")
        except Exception:
            color("○ 无法检测系统定时任务目录")
        
        # 条件3: 检查crontab命令可用性
        try:
            if os.name == 'nt':
                # Windows环境检查schtasks命令
                schtasks_result = ml('schtasks /query /fo list | findstr "TaskName"')
                if schtasks_result:
                    conditions_met.append("条件满足: schtasks命令可用")
                    color("✓ schtasks命令可用")
                else:
                    color("○ schtasks命令不可用")
            else:
                # Linux/Unix环境检查crontab命令
                crontab_path = ml('which crontab 2>/dev/null').strip()
                if crontab_path:
                    conditions_met.append("条件满足: crontab命令可用")
                    color("✓ crontab命令可用: {}".format(crontab_path))
                    
                    # 检查crontab权限
                    try:
                        crontab_test = ml('crontab -l 2>&1')
                        if 'no crontab' in crontab_test.lower() or 'crontab:' in crontab_test.lower():
                            conditions_met.append("条件满足: 可访问crontab")
                            color("✓ 可访问crontab")
                        elif crontab_test.strip():
                            conditions_met.append("条件满足: 存在用户crontab")
                            color("✓ 存在用户crontab")
                    except Exception:
                        color("○ crontab访问受限")
                else:
                    color("○ crontab命令不可用")
        except Exception:
            color("○ 无法检测定时任务命令")
        
        # 条件4: 检查用户cron权限
        try:
            current_user = _execute_platform_command('whoami')
            if current_user:
                if os.name == 'nt':
                    # Windows环境检查当前用户的任务计划权限
                    user_tasks = ml('schtasks /query /fo list | findstr /i "{}"'.format(current_user))
                    if user_tasks or True:  # Windows用户通常都有基本的任务计划权限
                        conditions_met.append("条件满足: 用户具有任务计划权限")
                        color("✓ 用户{}具有任务计划权限".format(current_user))
                else:
                    # Linux/Unix环境检查/etc/cron.allow和/etc/cron.deny
                    if os.path.exists('/etc/cron.allow'):
                        try:
                            with open('/etc/cron.allow', 'r') as f:
                                allowed_users = f.read()
                                if current_user in allowed_users:
                                    conditions_met.append("条件满足: 用户在cron.allow中")
                                    color("✓ 用户{}在cron.allow中".format(current_user))
                                else:
                                    color("○ 用户{}不在cron.allow中".format(current_user))
                        except Exception:
                            color("○ 无法读取cron.allow")
                    elif os.path.exists('/etc/cron.deny'):
                        try:
                            with open('/etc/cron.deny', 'r') as f:
                                denied_users = f.read()
                                if current_user not in denied_users:
                                    conditions_met.append("条件满足: 用户不在cron.deny中")
                                    color("✓ 用户{}不在cron.deny中".format(current_user))
                                else:
                                    color("○ 用户{}在cron.deny中".format(current_user))
                        except Exception:
                            color("○ 无法读取cron.deny")
                    else:
                        # 默认情况下，如果没有cron.allow和cron.deny，所有用户都可以使用cron
                        conditions_met.append("条件满足: 默认允许使用cron")
                        color("✓ 默认允许用户{}使用cron".format(current_user))
        except Exception:
            color("○ 无法检测用户定时任务权限")
        
        # 总结条件检测结果
        color_title("Crontab后门条件总结")
        if conditions_met:
            color("满足 {} 个Crontab后门条件:".format(len(conditions_met)))
            for condition in conditions_met:
                color("  • {}".format(condition))
        else:
            color("未满足Crontab后门的基本条件")
            
    except Exception as e:
        color_red("Crontab后门条件检测失败: {}".format(e))


def check_strace():
    """检查strace后门条件"""
    color_title("Strace后门条件检测")
    
    conditions_met = []
    
    try:
        # 条件1: 检查strace命令可用性
        try:
            if os.name == 'nt':
                # Windows环境检查Process Monitor或类似工具
                procmon_result = ml('powershell "Get-Command procmon -ErrorAction SilentlyContinue"')
                if procmon_result:
                    conditions_met.append("条件满足: Process Monitor可用")
                    color("✓ Process Monitor可用")
                else:
                    color("○ Process Monitor不可用")
            else:
                # Linux/Unix环境检查strace命令
                strace_path = ml('which strace 2>/dev/null').strip()
                if strace_path:
                    conditions_met.append("条件满足: strace命令可用")
                    color("✓ strace命令可用: {}".format(strace_path))
                else:
                    color("○ strace命令不可用")
        except Exception:
            color("○ 无法检测进程跟踪工具")
        
        # 条件2: 检查ptrace权限
        try:
            if os.name == 'nt':
                # Windows环境检查调试权限
                debug_privilege = ml('powershell "whoami /priv | findstr SeDebugPrivilege"')
                if 'SeDebugPrivilege' in debug_privilege:
                    conditions_met.append("条件满足: 具有调试权限")
                    color("✓ 具有调试权限")
                else:
                    color("○ 缺少调试权限")
            else:
                # Linux/Unix环境检查ptrace权限
                ptrace_scope = '/proc/sys/kernel/yama/ptrace_scope'
                if os.path.exists(ptrace_scope):
                    try:
                        with open(ptrace_scope, 'r') as f:
                            scope_value = f.read().strip()
                            if scope_value == '0':
                                conditions_met.append("条件满足: ptrace权限开放")
                                color("✓ ptrace权限开放 (scope: {})".format(scope_value))
                            else:
                                color("○ ptrace权限受限 (scope: {})".format(scope_value))
                    except Exception:
                        color("○ 无法读取ptrace配置")
                else:
                    # 如果文件不存在，通常意味着没有限制
                    conditions_met.append("条件满足: 无ptrace限制")
                    color("✓ 无ptrace限制")
        except Exception:
            color("○ 无法检测ptrace权限")
        
        # 条件3: 检查当前用户权限
        try:
            current_user = _execute_platform_command('whoami')
            if current_user:
                if os.name == 'nt':
                    # Windows环境检查管理员权限
                    admin_check = ml('powershell "([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] \'Administrator\')"')
                    if 'True' in admin_check:
                        conditions_met.append("条件满足: 具有管理员权限")
                        color("✓ 当前用户{}具有管理员权限".format(current_user))
                    else:
                        color("○ 当前用户{}无管理员权限".format(current_user))
                else:
                    # Linux/Unix环境检查root权限或sudo权限
                    if current_user == 'root':
                        conditions_met.append("条件满足: root用户")
                        color("✓ 当前用户为root")
                    else:
                        # 检查sudo权限
                        sudo_check = ml('sudo -n true 2>/dev/null && echo "success" || echo "failed"').strip()
                        if sudo_check == 'success':
                            conditions_met.append("条件满足: 具有sudo权限")
                            color("✓ 当前用户{}具有sudo权限".format(current_user))
                        else:
                            color("○ 当前用户{}无sudo权限".format(current_user))
        except Exception:
            color("○ 无法检测用户权限")
        
        # 条件4: 检查当前用户strace使用情况
        try:
            current_user = _execute_platform_command('whoami')
            if current_user:
                if os.name == 'nt':
                    # Windows环境检查Process Monitor使用情况
                    procmon_test = ml('powershell "Get-Process | Where-Object {$_.ProcessName -like \'*procmon*\'} | Measure-Object | Select-Object Count"')
                    if '0' not in procmon_test:
                        conditions_met.append("条件满足: 当前用户可使用进程监控")
                        color("✓ 当前用户{}可使用进程监控".format(current_user))
                    else:
                        color("○ 当前用户{}无法使用进程监控".format(current_user))
                else:
                    # Linux/Unix环境检查strace使用情况
                    test_result = ml('strace -e trace=write echo "test" 2>&1 | grep -q "write" && echo "success" || echo "failed"').strip()
                    if test_result == 'success':
                        conditions_met.append("条件满足: 当前用户可使用strace")
                        color("✓ 当前用户{}可使用strace".format(current_user))
                    else:
                        color("○ 当前用户{}无法使用strace".format(current_user))
        except Exception:
            color("○ 无法测试进程跟踪使用权限")
        
        # 条件5: 检查可疑的strace进程
        try:
            strace_processes = _execute_platform_command('ps_grep_strace')
            if strace_processes:
                conditions_met.append("条件满足: 发现进程跟踪进程")
                color("⚠ 发现运行中的进程跟踪进程:")
                for process in strace_processes.split('\n'):
                    if process.strip():
                        color("  {}".format(process.strip()))
            else:
                color("○ 未发现进程跟踪进程")
        except Exception:
            color("○ 无法检测进程跟踪进程")
        
        # 总结条件检测结果
        color_title("Strace后门条件总结")
        if conditions_met:
            color("满足 {} 个Strace后门条件:".format(len(conditions_met)))
            for condition in conditions_met:
                color("  • {}".format(condition))
        else:
            color("未满足Strace后门的基本条件")
            
    except Exception as e:
        color_red("Strace后门条件检测失败: {}".format(e))


def check_ssh_config():
    """检查SSH配置文件后门条件"""
    color_title("SSH配置文件后门条件检测")
    
    try:
        conditions_met = []
        
        # 条件1: 检查SSH配置文件存在性
        ssh_config_file = '/etc/ssh/sshd_config'
        try:
            if os.path.exists(ssh_config_file):
                conditions_met.append("条件满足: SSH配置文件存在")
                color("✓ SSH配置文件存在: {}".format(ssh_config_file))
            else:
                color("○ SSH配置文件不存在: {}".format(ssh_config_file))
        except Exception:
            color("○ 无法检测SSH配置文件")
        
        # 条件2: 检查SSH配置文件可写性
        try:
            if os.access(ssh_config_file, os.W_OK):
                conditions_met.append("条件满足: SSH配置文件可写")
                color("✓ SSH配置文件可写: {}".format(ssh_config_file))
            else:
                color("○ SSH配置文件不可写: {}".format(ssh_config_file))
        except Exception:
            color("○ 无法检测SSH配置文件权限")
        
        # 条件3: 检查SSH配置文件可读性
        try:
            if os.access(ssh_config_file, os.R_OK):
                conditions_met.append("条件满足: SSH配置文件可读")
                color("✓ SSH配置文件可读: {}".format(ssh_config_file))
            else:
                color("○ SSH配置文件不可读: {}".format(ssh_config_file))
        except Exception:
            color("○ 无法检测SSH配置文件读权限")
        
        # 条件4: 检查SSH服务状态
        try:
            ssh_service_running = check_ssh_service_status()
            
            if ssh_service_running:
                conditions_met.append("条件满足: SSH服务运行中")
                color("✓ SSH服务运行中")
            else:
                color("○ SSH服务未运行")
        except Exception:
            color("○ 无法检测SSH服务状态")
        
        # 条件5: 检查SSH配置目录权限
        try:
            ssh_config_dir = '/etc/ssh'
            if os.path.exists(ssh_config_dir) and os.access(ssh_config_dir, os.W_OK):
                conditions_met.append("条件满足: SSH配置目录可写")
                color("✓ SSH配置目录可写: {}".format(ssh_config_dir))
            else:
                color("○ SSH配置目录不可写: {}".format(ssh_config_dir))
        except Exception:
            color("○ 无法检测SSH配置目录权限")
        
        # 条件6: 检查当前用户权限
        try:
            current_user = ml('whoami').strip()
            if current_user == 'root':
                conditions_met.append("条件满足: 当前用户为root")
                color("✓ 当前用户为root")
            else:
                color("○ 当前用户为: {} (非root)".format(current_user))
        except Exception:
            color("○ 无法检测当前用户")
        
        # 条件7: 检查SSH配置文件内容可修改性
        try:
            config_content = ml('cat {} 2>/dev/null'.format(ssh_config_file))
            if config_content.strip():
                conditions_met.append("条件满足: SSH配置文件内容可访问")
                color("✓ SSH配置文件内容可访问")
                
                # 检查关键配置项
                if 'PasswordAuthentication' in config_content:
                    color("  发现PasswordAuthentication配置")
                if 'PubkeyAuthentication' in config_content:
                    color("  发现PubkeyAuthentication配置")
                if 'PermitRootLogin' in config_content:
                    color("  发现PermitRootLogin配置")
            else:
                color("○ SSH配置文件内容不可访问")
        except Exception:
            color("○ 无法读取SSH配置文件内容")
        
        # 总结条件检测结果
        color_title("SSH配置文件后门条件总结")
        if conditions_met:
            color("满足 {} 个SSH配置文件后门条件:".format(len(conditions_met)))
            for condition in conditions_met:
                color("  • {}".format(condition))
        else:
            color("未满足SSH配置文件后门的基本条件")
            
    except Exception as e:
        color_red("SSH配置文件后门条件检测失败: {}".format(e))


def list_files(directory):
    """列出目录中的文件"""
    files = []
    try:
        for filename in os.listdir(directory):
            filepath = os.path.join(directory, filename)
            if os.path.isfile(filepath):
                files.append(filepath)
    except Exception:
        pass
    return files


def is_ssh_key_login_enabled():
    """
    检查SSH密钥登录是否启用
    通过分析SSH配置文件来判断，而不是尝试实际连接
    """
    try:
        ssh_config_path = '/etc/ssh/sshd_config'
        
        # 检查配置文件是否存在
        if not os.path.exists(ssh_config_path):
            color_red("SSH configuration file not found", ssh_config_path)
            return False
            
        # 读取SSH配置文件
        with open(ssh_config_path, 'r') as f:
            config_content = f.read()
        
        # 检查关键配置项
        pubkey_auth_enabled = True  # 默认启用
        password_auth_enabled = True  # 默认启用
        
        # 解析配置文件
        for line in config_content.split('\n'):
            line = line.strip()
            if line.startswith('#') or not line:
                continue
                
            # 检查公钥认证设置
            if line.lower().startswith('pubkeyauthentication'):
                value = line.split()[-1].lower()
                pubkey_auth_enabled = value in ['yes', 'true', '1']
                
            # 检查密码认证设置
            elif line.lower().startswith('passwordauthentication'):
                value = line.split()[-1].lower()
                password_auth_enabled = value in ['yes', 'true', '1']
        
        # 输出检测结果
        if pubkey_auth_enabled:
            color("SSH公钥认证", "已启用")
            
            # 检查是否存在授权密钥文件
            auth_keys_paths = [
                os.path.expanduser('~/.ssh/authorized_keys'),
                '/root/.ssh/authorized_keys'
            ]
            
            keys_found = False
            for auth_path in auth_keys_paths:
                if os.path.exists(auth_path) and os.path.getsize(auth_path) > 0:
                    color("发现授权密钥文件", auth_path)
                    keys_found = True
            
            if not keys_found:
                color_red("警告", "公钥认证已启用但未找到授权密钥文件")
                
        else:
            color_red("SSH公钥认证", "已禁用")
            
        # 显示密码认证状态
        if password_auth_enabled:
            color("SSH密码认证", "已启用")
        else:
            color_red("SSH密码认证", "已禁用")
            
        print()
        return pubkey_auth_enabled
        
    except Exception as e:
        color_red("检查SSH密钥登录状态时出错", str(e))
        return False


def ssh_ip():
    """检查SSH相关信息和登录IP"""
    color_title('ssh')
    try:
        files = list_files("/root/.ssh/")
        is_ssh_key_login_enabled()
        for fi in files:
            if not ("known_hosts" in fi):
                if os.path.exists(fi):  # 判断存不存在
                    with open(fi, "r") as f:
                        color("ssh", fi)
                        print(f.read())
    except Exception:
        pass
    
    color_title('登录IP')
    distro_type = detect_linux_distro()
    if distro_type == 'debian_based':
        # Ubuntu/Debian系列使用auth.log
        print(ml("""grep "Accepted " /var/log/auth.log | awk '{print($11)}' | sort | uniq -c | sort -nr | more"""))
    elif distro_type == 'rhel_based':
        # RHEL系列（CentOS、Rocky Linux、AlmaLinux等）使用secure日志
        print(ml("""grep "Accepted " /var/log/secure* | awk '{print($11)}' | sort | uniq -c | sort -nr | more"""))
    elif distro_type == 'fedora_based':
        # Fedora/Fedora CoreOS系列，主要使用systemd journal
        safe_print("尝试检查systemd journal...")
        # 尝试多种SSH服务名称
        journal_result = ml("""journalctl -u sshd.service --no-pager 2>/dev/null | grep "Accepted " | awk '{print($11)}' | sort | uniq -c | sort -nr""")
        if not journal_result.strip():
            journal_result = ml("""journalctl -u ssh.service --no-pager 2>/dev/null | grep "Accepted " | awk '{print($11)}' | sort | uniq -c | sort -nr""")
        if not journal_result.strip():
            # 尝试更通用的journal查询
            journal_result = ml("""journalctl --no-pager 2>/dev/null | grep "sshd.*Accepted " | awk '{print($11)}' | sort | uniq -c | sort -nr""")
        
        if journal_result.strip():
            print(journal_result)
        else:
            safe_print("尝试检查传统日志文件...")
            # 备用：尝试传统日志文件（某些Fedora配置可能仍使用）
            secure_result = ml("""grep "Accepted " /var/log/secure* 2>/dev/null | awk '{print($11)}' | sort | uniq -c | sort -nr""")
            if secure_result.strip():
                print(secure_result)
            else:
                messages_result = ml("""grep "Accepted " /var/log/messages* 2>/dev/null | awk '{print($11)}' | sort | uniq -c | sort -nr""")
                if messages_result.strip():
                    print(messages_result)
                else:
                    color_red("未找到SSH登录日志")
    elif distro_type == 'suse_based':
        # SUSE/OpenSUSE系列，优先使用systemd journal，然后尝试传统日志文件
        safe_print("尝试检查systemd journal...")
        journal_result = ml("""journalctl -u sshd.service --no-pager 2>/dev/null | grep "Accepted " | awk '{print($11)}' | sort | uniq -c | sort -nr""")
        if not journal_result.strip():
            journal_result = ml("""journalctl -u ssh.service --no-pager 2>/dev/null | grep "Accepted " | awk '{print($11)}' | sort | uniq -c | sort -nr""")
        
        if journal_result.strip():
            print(journal_result)
        else:
            safe_print("尝试检查传统日志文件...")
            # 尝试/var/log/messages
            messages_result = ml("""grep "Accepted " /var/log/messages* 2>/dev/null | awk '{print($11)}' | sort | uniq -c | sort -nr""")
            if messages_result.strip():
                print(messages_result)
            else:
                # 尝试/var/log/secure
                secure_result = ml("""grep "Accepted " /var/log/secure* 2>/dev/null | awk '{print($11)}' | sort | uniq -c | sort -nr""")
                if secure_result.strip():
                    print(secure_result)
                else:
                    color_red("未找到SSH登录日志")
    else:
        # 未知系统，尝试多种日志文件
        safe_print("尝试检查auth.log...")
        auth_result = ml("""grep "Accepted " /var/log/auth.log 2>/dev/null | awk '{print($11)}' | sort | uniq -c | sort -nr | more""")
        if auth_result.strip():
            print(auth_result)
        else:
            safe_print("尝试检查secure日志...")
            secure_result = ml("""grep "Accepted " /var/log/secure* 2>/dev/null | awk '{print($11)}' | sort | uniq -c | sort -nr | more""")
            if secure_result.strip():
                print(secure_result)
            else:
                safe_print("尝试检查messages日志...")
                messages_result = ml("""grep "Accepted " /var/log/messages* 2>/dev/null | awk '{print($11)}' | sort | uniq -c | sort -nr""")
                if messages_result.strip():
                    print(messages_result)
                else:
                    color_red("未找到SSH登录日志")
    
    color_title('在线用户')
    print(ml("who"))
    color("ssh port", ml("netstat -tlnp | grep ssh"))


def check_system_info():
    """检测系统信息获取相关条件"""
    color_title("系统信息获取条件检测")
    conditions_met = 0
    total_conditions = 6
    
    try:
        # 检测系统类型识别能力
        distro_type = detect_linux_distro()
        
        # 发行版名称映射
        distro_names = {
            'debian_based': 'Debian/Ubuntu系列',
            'centos_based': 'CentOS系统',
            'centos_stream_based': 'CentOS Stream系列',
            'rhel_based': 'RHEL系列(Rocky/AlmaLinux/RHEL)',
            'fedora_based': 'Fedora系统',
            'suse_based': 'SUSE系列(openSUSE/SLES)',
            'arch_based': 'Arch Linux系列(Arch/Manjaro)',
            'alpine_based': 'Alpine Linux系统',
            'gentoo_based': 'Gentoo系统'
        }
        
        if distro_type in distro_names:
            color("系统类型识别", "可识别 - " + distro_names[distro_type])
            conditions_met += 1
        else:
            color("系统类型识别", "未知或其他Linux发行版")
        
        # 检测系统发行版信息文件可访问性
        if os.path.exists('/etc/os-release'):
            color("发行版信息文件", "可访问 (/etc/os-release)")
            conditions_met += 1
            try:
                content = system_info.safe_file_read('/etc/os-release')
                if content and 'PRETTY_NAME=' in content:
                    color("发行版详细信息", "可获取")
                    conditions_met += 1
                else:
                    color("发行版详细信息", "读取失败")
            except Exception as e:
                color("发行版详细信息", "读取失败")
        else:
            color("发行版信息文件", "不存在")
        
        # 检测内核信息获取能力
        try:
            import platform
            if os.name == 'nt':  # Windows 系统
                kernel_version = platform.release()
            else:  # Linux/Unix 系统
                kernel_version = ml('uname -r').strip()
            
            if kernel_version:
                color("内核版本获取", "可获取 - " + kernel_version)
                conditions_met += 1
            else:
                color("内核版本获取", "无法获取")
        except Exception:
            color("内核版本获取", "无法获取")
            
        # 检测系统架构获取能力
        try:
            import platform
            if os.name == 'nt':  # Windows 系统
                arch = platform.machine()
            else:  # Linux/Unix 系统
                arch = ml('uname -m').strip()
            
            if arch:
                color("系统架构获取", "可获取 - " + arch)
                conditions_met += 1
            else:
                color("系统架构获取", "无法获取")
        except Exception:
            color("系统架构获取", "无法获取")
            
        # 检测命令执行权限
        try:
            test_cmd = ml('whoami').strip()
            if test_cmd:
                color("命令执行权限", "具备")
                conditions_met += 1
            else:
                color("命令执行权限", "受限")
        except:
            color("命令执行权限", "受限")
            
    except Exception as e:
        # 安全地处理异常信息，避免编码错误
        try:
            error_msg = str(e)
        except UnicodeEncodeError:
            error_msg = repr(e)
        color_red("系统信息检测过程出错", error_msg)
    
    # 输出条件检测结果
    color("条件检测结果", "{}/{} 个条件满足".format(conditions_met, total_conditions))
    if conditions_met >= 4:
        color("风险评估", "系统信息获取条件充分，便于后续攻击")
    elif conditions_met >= 2:
        color("风险评估", "部分系统信息可获取，存在一定风险")
    else:
        color("风险评估", "系统信息获取受限，风险较低")